Skip to content

fix(anthropic): Only finish relevant spans in .create() patches#5716

Merged
alexander-alderman-webb merged 9 commits intomasterfrom
webb/anthropic/remove-get-current-span
Apr 9, 2026
Merged

fix(anthropic): Only finish relevant spans in .create() patches#5716
alexander-alderman-webb merged 9 commits intomasterfrom
webb/anthropic/remove-get-current-span

Conversation

@alexander-alderman-webb
Copy link
Copy Markdown
Contributor

@alexander-alderman-webb alexander-alderman-webb commented Mar 20, 2026

Description

Anthropic spans are only created in _sentry_patched_create() and _sentry_patched_create_async().

Exit spans in these functions when the anthropic library function raises an exception.

Resolves an edge case where _sentry_patched_create() or _sentry_patched_create_async() exits early and does not create a span and get_current_span() therefore returns a non-anthropic span.

Issues

Reminders

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 20, 2026

Semver Impact of This PR

🟢 Patch (bug fixes)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (ai) Redact base64 data URLs in image_url content blocks by ericapisani in #5953
  • (integrations) Instrument pyreqwest tracing by servusdei2018 in #5682

Bug Fixes 🐛

  • (anthropic) Only finish relevant spans in .create() patches by alexander-alderman-webb in #5716
  • (wsgi) Respect HTTP_X_FORWARDED_PROTO in request.url construction by sl0thentr0py in #5963

Internal Changes 🔧

  • (anthropic) Separate sync and async .create() patches by alexander-alderman-webb in #5715
  • (openai) Split token counting by API for easier deprecation by ericapisani in #5930
  • (opentelemetry) Ignore mypy error by alexander-alderman-webb in #5927
  • Fix license metadata in setup.py by sl0thentr0py in #5934
  • Update validate-pr workflow by stephanie-anderson in #5931

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 20, 2026

Codecov Results 📊

13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 8.36s

All tests are passing successfully.

❌ Patch coverage is 20.00%. Project has 14846 uncovered lines.

Files with missing lines (1)
File Patch % Lines
anthropic.py 5.81% ⚠️ 405 Missing

Generated by Codecov Action

@alexander-alderman-webb alexander-alderman-webb marked this pull request as ready for review April 2, 2026 08:55
@alexander-alderman-webb alexander-alderman-webb requested a review from a team as a code owner April 2, 2026 08:55
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Copy link
Copy Markdown
Member

@ericapisani ericapisani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any test coverage that we can add here to confirm this behaviour? Otherwise LGTM

@alexander-alderman-webb
Copy link
Copy Markdown
Contributor Author

Is there any test coverage that we can add here to confirm this behaviour? Otherwise LGTM

In my view a regression test has limited use in this case because an integration should not be touching spans created outside the integration (unless it's for an agreed-upon reason, i.e., not duplicating spans between openai-agents and openai).

For the future, here's a script that verifies that demonstrates the edge case I'm addressing below. The messages argument is missing from the call to create() and the outer transaction is closed prematurely since it's status is INTERNAL_ERROR.

import sentry_sdk
from sentry_sdk.tracing import SPANSTATUS
from sentry_sdk.integrations.anthropic import AnthropicIntegration
from anthropic import Anthropic

sentry_sdk.init(
    dsn="",
    integrations=[AnthropicIntegration()],
    traces_sample_rate=1.0,
)

def main():
    client = Anthropic(api_key="dummy")
    with sentry_sdk.start_transaction(name="parent", op="test") as transaction:
        transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
        try:
            client.messages.create(max_tokens=1024, model="model", stream=False)
        except Exception as e:
            print(f"Expected exception: {e}")

if __name__ == "__main__":
    main()

@ericapisani
Copy link
Copy Markdown
Member

In my view a regression test has limited use in this case because an integration should not be touching spans created outside the integration (unless it's for an agreed-upon reason, i.e., not duplicating spans between openai-agents and openai).

I agree with what you're saying regarding an integration not touching spans created outside of it, but I think we could ensure that this edge case is resolved with a test that confirms that an anthropic span is present when the conditions that caused it are set.

To give a picture of what I'm envisioning (I used the script you've provided as the basis for it):

    sentry_init(integrations=[AnthropicIntegration()], traces_sample_rate=1.0)
    events = capture_events()

    client = Anthropic(api_key="z")
    client.messages._post = mock.Mock(return_value=EXAMPLE_MESSAGE)

    with start_transaction(name="anthropic") as transaction:
        transaction.set_status(SPANSTATUS.INTERNAL_ERROR)
        client.messages.create(
           # No messages value passed in
            model="model",
            max_tokens=1024,
            stream=False
        )

    (tx,) = events

    assert len(tx["spans"]) == 1
    span = tx["spans"][0]

    assert span["data"][SPANDATA.GEN_AI_SYSTEM] == "anthropic"

What do you think? Also happy to pair on this tomorrow when you're back online 😄

Base automatically changed from webb/anthropic/separate-sync-and-async to master April 9, 2026 07:32
@alexander-alderman-webb alexander-alderman-webb merged commit 45abbe3 into master Apr 9, 2026
158 checks passed
@alexander-alderman-webb alexander-alderman-webb deleted the webb/anthropic/remove-get-current-span branch April 9, 2026 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants